package org.tinygroup.bizframe.action;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.tinygroup.beancontainer.BeanContainerFactory;
import org.tinygroup.bizframe.common.BaseController;
import org.tinygroup.bizframe.service.inter.dto.TreeDto;
import org.tinygroup.cepcore.CEPCore;
import org.tinygroup.commons.tools.ReflectionUtils;
import org.tinygroup.commons.tools.StringUtil;
import org.tinygroup.context.Context;
import org.tinygroup.context.impl.ContextImpl;
import org.tinygroup.event.Event;
import org.tinygroup.event.ServiceInfo;
import org.tinygroup.logger.Logger;
import org.tinygroup.logger.LoggerFactory;



@Controller()
@RequestMapping("/rest")
public class RestAction extends BaseController {

	private static final Logger logger = LoggerFactory.getLogger(RestAction.class);
	private static CEPCore cepCore = null;

	@RequestMapping(value = "/get/{beanName}/{key}")
	@ResponseBody
	public Object fetchOne(@PathVariable String beanName, @PathVariable String key, Model model) {
		String serviceId = "get" + StringUtil.capitalize(StringUtil.toCamelCase(beanName));
		Context context = new ContextImpl();
		context.put("key", key);
		Map<String, Object> ret = null;

		ret = process(serviceId, context);
		if ("y".equals(ret.get("status")) == false) {
			return ret;
		}

		ServiceInfo svcInfo = getCepCore().getServiceInfo(serviceId);

		String retKey = svcInfo.getResults().get(0).getName();
		Object retObj = ret.get(retKey);
		if (retObj == null) {
			return resultMap(false, "对象不存在");
		}
		return retObj;

	}

	protected Map<String, Object> process(String serviceId, Context context) {
		Map<String, Object> ret = new HashMap<String, Object>();
		ServiceInfo svcInfo = getCepCore().getServiceInfo(serviceId);
		if (svcInfo == null) {
			return resultMap(false, "资源不存在");
		}
		Event event = Event.createEvent(serviceId, context);

		getCepCore().process(event);
		ret = resultMap(true, context.getItemMap());
		return ret;
	}

	@RequestMapping(value = "/find/{beanName}")
	@ResponseBody
	public Object find(@PathVariable String beanName, HttpServletRequest request, Model model) {
		String serviceId = "query" + StringUtil.capitalize(StringUtil.toCamelCase(beanName));
		Enumeration en = request.getParameterNames();
		Context context = new ContextImpl();
		while (en.hasMoreElements()) {
			String name = (String) en.nextElement();
			context.put(name, request.getParameter(name));
		}
		Map<String, Object> ret = new HashMap<String, Object>();
		ret = process(serviceId, context);
		if ("y".equals(ret.get("status")) == false) {
			return ret;
		}

		ServiceInfo svcInfo = getCepCore().getServiceInfo(serviceId);

		String retKey = svcInfo.getResults().get(0).getName();
		return context.get(retKey);
	}

	@RequestMapping(value = "/one/{beanName}")
	@ResponseBody
	public Object findOne(@PathVariable String beanName, HttpServletRequest request, Model model) {
		String serviceId = "query" + StringUtil.capitalize(StringUtil.toCamelCase(beanName));
		Enumeration en = request.getParameterNames();
		Context context = new ContextImpl();
		while (en.hasMoreElements()) {
			String name = (String) en.nextElement();
			context.put(name, request.getParameter(name));
		}
		Map<String, Object> ret = null;

		ret = process(serviceId, context);

		if ("y".equals(ret.get("status")) == false) {
			return ret;
		}
		ServiceInfo svcInfo = getCepCore().getServiceInfo(serviceId);

		String retKey = svcInfo.getResults().get(0).getName();
		Object lsRet = context.get(retKey);
		if (lsRet != null && lsRet instanceof List) {
			if (((List) lsRet).isEmpty()) {
				return new ArrayList<Object>();
			}
			return ((List) lsRet).get(0);
		}
		return ret;
	}

	@RequestMapping(value = "/save/{beanName}", method = RequestMethod.POST)
	@ResponseBody
	public Object save(@PathVariable String beanName, HttpServletRequest request, Model model) {
		String serviceId = "add" + StringUtil.capitalize(StringUtil.toCamelCase(beanName));
		Enumeration en = request.getParameterNames();
		Context context = new ContextImpl();
		while (en.hasMoreElements()) {
			String name = (String) en.nextElement();
			context.put(name, request.getParameter(name));
		}
		Map<String, Object> ret = null;

		ret = process(serviceId, context);
		return ret;
	}

	@RequestMapping(value = "/update/{beanName}/{id}", method = RequestMethod.POST)
	@ResponseBody
	public Object update(@PathVariable String beanName, @PathVariable Long id, HttpServletRequest request,
			Model model) {
		String serviceId = "update" + StringUtil.capitalize(StringUtil.toCamelCase(beanName));
		Enumeration en = request.getParameterNames();
		Context context = new ContextImpl();
		while (en.hasMoreElements()) {
			String name = (String) en.nextElement();
			context.put(name, request.getParameter(name));
		}
		context.put("id", id);
		Map<String, Object> ret = null;

		ret = process(serviceId, context);

		return ret;
	}

	@RequestMapping(value = "/select/{beanName}", method = { RequestMethod.POST, RequestMethod.GET })
	@ResponseBody
	public Object query(@PathVariable String beanName, String dataId, String dataName, HttpServletRequest request,
			Model model) throws Throwable {
		String serviceId = "query" + StringUtil.capitalize(StringUtil.toCamelCase(beanName));
		Enumeration en = request.getParameterNames();
		Context context = new ContextImpl();
		while (en.hasMoreElements()) {
			String name = (String) en.nextElement();
			context.put(name, request.getParameter(name));
		}
		Map<String, Object> ret = null;
		if (StringUtils.isEmpty(dataId)) {
			dataId = "id";
		}
		if (StringUtils.isEmpty(dataName)) {
			dataName = "name";
		}
		ret = process(serviceId, context);
		if ("y".equals(ret.get("status")) == false) {
			throw new RuntimeException("查询异常" + ret.get("info"));
		}

		ServiceInfo svcInfo = getCepCore().getServiceInfo(serviceId);

		String retKey = svcInfo.getResults().get(0).getName();
		Object objRet = context.get(retKey);
		if (objRet != null && objRet instanceof List) {
			if (((List) objRet).isEmpty()) {
				return new ArrayList<Object>();
			}
			List<Object> lsRet = new ArrayList<Object>();
			Iterator itr = ((List) objRet).iterator();
			while (itr.hasNext()) {
				Object row = itr.next();
				Class clazz = row.getClass();
				Field fldId = ReflectionUtils.findField(clazz, dataId);
				Field fldName = ReflectionUtils.findField(clazz, dataName);
				logger.warnMessage(clazz.getName());
				
				if (fldName == null || fldId == null) {
					throw new RuntimeException("属性" + dataName + " 或者 " + dataId + "不存在");
				}
				Map<String, Object> item = new HashMap<String, Object>();
				fldId.setAccessible(true);
				fldName.setAccessible(true);
				ReflectionUtils.getField(fldId,row);
				item.put("id", ReflectionUtils.getField(fldId, row));
				item.put("text", ReflectionUtils.getField(fldName, row));
				lsRet.add(item);
			}

			return lsRet;

		}
		return new ArrayList<Object>();
	}
	
	@RequestMapping(value = "/tree/{beanName}", method = { RequestMethod.POST, RequestMethod.GET })
	@ResponseBody
	public Object queryTree(@PathVariable String beanName, String dataId, String dataName,String parentId, HttpServletRequest request,
			Model model) throws Throwable {
		String serviceId = "query" + StringUtil.capitalize(StringUtil.toCamelCase(beanName));
		Enumeration en = request.getParameterNames();
		Context context = new ContextImpl();
		while (en.hasMoreElements()) {
			String name = (String) en.nextElement();
			context.put(name, request.getParameter(name));
		}
		Map<String, Object> ret = null;
		if (StringUtils.isEmpty(dataId)) {
			dataId = "id";
		}
		if (StringUtils.isEmpty(parentId)) {
			parentId = "parentId";
		}
		if (StringUtils.isEmpty(dataName)) {
			dataName = "name";
		}
		ret = process(serviceId, context);
		if ("y".equals(ret.get("status")) == false) {
			throw new RuntimeException("查询异常" + ret.get("info"));
		}

		ServiceInfo svcInfo = getCepCore().getServiceInfo(serviceId);

		String retKey = svcInfo.getResults().get(0).getName();
		Object objRet = context.get(retKey);
		if (objRet != null && objRet instanceof List) {
			if (((List) objRet).isEmpty()) {
				return new ArrayList<Object>();
			}
			List<Object> lsRet = new ArrayList<Object>();
			Iterator itr = ((List) objRet).iterator();
			while (itr.hasNext()) {
				Object row = itr.next();
				Class clazz = row.getClass();
				Field fldId = ReflectionUtils.findField(clazz, dataId);
				Field fldName = ReflectionUtils.findField(clazz, dataName);
				Field fldParent = ReflectionUtils.findField(clazz, parentId);
				
				if (fldName == null || fldId == null) {
					throw new RuntimeException("属性" + dataName + " 或者 " + dataId + "不存在");
				}
				TreeDto tree = new  TreeDto();
				fldId.setAccessible(true);
				fldName.setAccessible(true);
				tree.setId(ReflectionUtils.getField(fldId, row)+"");
				tree.setName(ReflectionUtils.getField(fldName, row)+"");
				if(fldParent!=null){
					fldParent.setAccessible(true);
					tree.setpId(ReflectionUtils.getField(fldParent, row)+"");
				}
				lsRet.add(tree);
			}

			return lsRet;

		}
		return new ArrayList<Object>();
	}


	@RequestMapping(value = "/page/{beanName}", method = { RequestMethod.POST, RequestMethod.GET })
	@ResponseBody
	public Object queryPage(@PathVariable String beanName, HttpServletRequest request, Model model) {
		String serviceId = "query" + StringUtil.capitalize(StringUtil.toCamelCase(beanName)) + "Pager";
		Enumeration en = request.getParameterNames();
		Context context = new ContextImpl();
		while (en.hasMoreElements()) {
			String name = (String) en.nextElement();
			context.put(name, request.getParameter(name));
		}
		Map<String, Object> ret = new HashMap<String, Object>();

		ret = process(serviceId, context);
		if ("y".equals(ret.get("status")) == false) {
			return ret;
		}

		ServiceInfo svcInfo = getCepCore().getServiceInfo(serviceId);

		String retKey = svcInfo.getResults().get(0).getName();
		return context.get(retKey);
	}

	public CEPCore getCepCore() {
		if (cepCore == null) {
			cepCore = BeanContainerFactory.getBeanContainer(BeanContainerFactory.class.getClassLoader())
					.getBean("cepcore");
		}
		return cepCore;
	}

}
